package com.chinacoal.microservice.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.chinacoal.microservice.mapper.*;
import com.chinacoal.microservice.pojo.*;
import com.chinacoal.microservice.service.WechatOfficialAccountService;
import com.chinacoal.microservice.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author zhuliang
 * @version V1.0
 * @Description: 微信公众号-后端实现类
 * @date 2020-12-23 10：16
 */
@Service
@Slf4j
public class WechatOfficialAccountServiceImpl implements WechatOfficialAccountService {

    @Autowired
    private CcmsSmartleasingWorkOrderMapper workOrderMapper;

    @Autowired
    private CcmsSmartleasingTenantMapper tenantMapper;

    @Autowired
    private CcmsSmartleasingContractMapper contractMapper;

    @Autowired
    private CcmsSmartleasingExpenseManagMapper expenseManagMapper;

    @Autowired
    private CcmsSmartleasingNoticeMapper noticeMapper;

    @Autowired
    private CcmsSmartleasingInvoiceRecordMapper invoiceRecordMapper;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private BasicConfiguration basicConfiguration;

    @Autowired
    private CcmsSmartleasingRoomMapper roomMapper;

    @Autowired
    private CcmsSmartleasingHistoricalPaymentMapper historicalPaymentMapper;

    @Autowired
    private CcmsSmartleasingRegionalAnalysisMapper regionalAnalysisMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * @Description: 微信端-我的房间
     * @author zhuliang
     * @date 2020/12/23 9:41
     */
    @Override
    public Result<List<CcmsSmartleasingContract>> getRoomByWechat(String token) {
        //得到租户联系方式
        String phone = JWT.decode(token).getClaim("phone").asString();

        //根据租户id查询我的房间
        List<CcmsSmartleasingContract> contracts = contractMapper.getAllByRoom(phone);

        return Result.success(contracts);
    }

    /**
     * @Description: 微信端-工单信息列表
     * @author zhuliang
     * @date 2020/12/23 9:54
     */
    @Override
    public Result<List<CcmsSmartleasingWorkOrder>> getWorkOrderListByWechat(String token) {
        //得到租户联系方式
        String phone = JWT.decode(token).getClaim("phone").asString();

        //查询所有的工单信息
        List<CcmsSmartleasingWorkOrder> workOrders = workOrderMapper.getAll(phone);

        //判断是否已经处理了
        for (CcmsSmartleasingWorkOrder workOrder : workOrders) {
            if (null != workOrder && "1".equals(workOrder.getWorkOrderStatus()) && StringUtils.isNotBlank(workOrder.getScenePicture())) {
                //拆分图片地址
                String[] split = workOrder.getScenePicture().split(",");
                workOrder.setScenePictureList(split);
            }
        }

        return Result.success(workOrders);
    }

    /**
     * @Description: 微信端-新增工单信息的回显
     * @author zhuliang
     * @date 2020/12/23 10:31
     */
    @Override
    public Result<CcmsSmartleasingTenant> workOrderEcho(String token) {
        //得到租户联系方式
        String phone = JWT.decode(token).getClaim("phone").asString();

        //得到回显信息
        CcmsSmartleasingTenant tenant = tenantMapper.getNameByWechat(phone);

        return Result.success(tenant);
    }

    /**
     * @Description: 微信端-新增工单信息
     * @author zhuliang
     * @date 2020/12/23 10:42
     */
    @Override
    public Result addWorkOrder(String token, CcmsSmartleasingWorkOrder workOrder) {
        //完善工单信息
        workOrder.setLastUpdatedBy(0);
        workOrder.setLastUpdateDate(new Date());
        workOrder.setCreatedBy(0);
        workOrder.setCreationDate(new Date());
        workOrder.setPkWorkOrderId(UUID.randomUUID() + "");
        workOrder.setWorkOrderStatus("0");

        //添加工单信息
        workOrderMapper.insert(workOrder);

        return Result.success();
    }

    /**
     * @Description: 微信端-修改个人信息
     * @author zhuliang
     * @date 2020/12/23 10:53
     */
    @Override
    public Result updateTenantByWechat(String token, CcmsSmartleasingTenant tenant) {
        //得到租户联系方式
        String phone = JWT.decode(token).getClaim("phone").asString();

        //修改租户信息
        tenantMapper.updateData(tenant.getEmail(), phone, null);

        return Result.success();
    }

    /**
     * @Description: 微信端-所有已缴费费用信息(带分页)
     * @author zhuliang
     * @date 2020/12/23 11:20
     */
    @Override
    public Result<List<CcmsSmartleasingExpenseManag>> getAllExpenseManagByWechat(String token, QueryCriteria queryCriteria) {
        //得到租户联系方式
        String phone = JWT.decode(token).getClaim("phone").asString();

        //查询费用信息
        List<CcmsSmartleasingExpenseManag> expenseManags = expenseManagMapper.getAllByWechat((queryCriteria.getPage() - 1) * queryCriteria.getPageSize(), queryCriteria.getPageSize(), phone);

        //计算其他费用
        for (CcmsSmartleasingExpenseManag expenseManag : expenseManags) {
            expenseManag.setOtherExpenses(expenseManag.getTotalAmount().subtract(expenseManag.getMonthlyRent()));
        }

        return Result.success(expenseManags);
    }

    /**
     * @Description: 微信端-所有未缴费费用信息
     * @author zhuliang
     * @date 2020/12/23 14:55
     */
    @Override
    public Result<List<CcmsSmartleasingExpenseManag>> getUnpaidFeesInformationByWechat(String token) {
        //得到租户联系方式
        String phone = JWT.decode(token).getClaim("phone").asString();

        //查询费用信息
        List<CcmsSmartleasingExpenseManag> expenseManags = expenseManagMapper.getUnpaidFeesByWechat(phone);

        //计算其他费用
        for (CcmsSmartleasingExpenseManag expenseManag : expenseManags) {
            expenseManag.setOtherExpenses(expenseManag.getTotalAmount().subtract(expenseManag.getMonthlyRent()));
        }

        return Result.success(expenseManags);
    }

    /**
     * @Description: 微信端-根据费用id查询通知单信息
     * @author zhuliang
     * @date 2020/12/23 15:29
     */
    @Override
    public Result<CcmsSmartleasingNotice> getNoticeById(String fkExpenseManagId, String token, Integer type) {
        //根据费用id查询通知单信息
        CcmsSmartleasingNotice notice = noticeMapper.getNoticeByWechat(fkExpenseManagId);

        //计算其他费用的小计
        notice.setOtherSubtotal(new BigDecimal(0));
        if (null != notice.getDrainageFee()) {
            notice.setOtherSubtotal(notice.getOtherSubtotal().add(notice.getDrainageFee()));
        }
        if (null != notice.getTelephoneRate()) {
            notice.setOtherSubtotal(notice.getOtherSubtotal().add(notice.getTelephoneRate()));
        }
        if (null != notice.getComprehensiveManagementRate()) {
            notice.setOtherSubtotal(notice.getOtherSubtotal().add(notice.getComprehensiveManagementRate()));
        }
        if (null != notice.getSanitationFee()) {
            notice.setOtherSubtotal(notice.getOtherSubtotal().add(notice.getSanitationFee()));
        }
        if (null != notice.getElevatorRate()) {
            notice.setOtherSubtotal(notice.getOtherSubtotal().add(notice.getElevatorRate()));
        }
        if (null != notice.getTrashHandlingFee()) {
            notice.setOtherSubtotal(notice.getOtherSubtotal().add(notice.getTrashHandlingFee()));
        }
        if (null != notice.getGasInsurance()) {
            notice.setOtherSubtotal(notice.getOtherSubtotal().add(notice.getGasInsurance()));
        }

        //判断是缴费页面，还是查询页面
        if (0 == type) {
            return Result.success(notice);
        } else if (StringUtils.isNotBlank(notice.getInvoiceMethod()) && "1".equals(notice.getInvoiceMethod())) {
            return Result.success(notice);
        } else if (StringUtils.isNotBlank(notice.getInvoiceStatus()) && "1".equals(notice.getInvoiceStatus())) {
            //查询开票记录
            List<CcmsSmartleasingInvoiceRecord> invoiceRecord = invoiceRecordMapper.getInvoice(notice.getPkNoticeId());

            // 兼容性处理
            if (null == invoiceRecord || invoiceRecord.size() == 0) {
                log.error(CodeMsg.NOT_FOUND + "-->此开票记录不存在" + notice.getFkInvoiceRecordId());
                return Result.error(CodeMsg.NOT_FOUND);
            }

            notice.setInvoiceRecord(invoiceRecord);

            return Result.success(notice);
        } else {
            return Result.success(notice);
        }





        // //查询开票方式，如果是线下开票，则不执行后面代码
        // String method = contractMapper.queryBillingMethod(fkExpenseManagId);
        // if ("0".equals(method)) {
        //     //先去数据库查询是否不是第一次开票
        //     CcmsSmartleasingInvoiceRecord invoiceRecord = invoiceRecordMapper.getInvoice(notice.getFkInvoiceRecordId());
        //
        //     //兼容性处理
        //     if (null == invoiceRecord) {
        //         log.error(CodeMsg.NOT_FOUND.toString() + "-->此开票记录不存在" + notice.getFkInvoiceRecordId());
        //         return Result.error(CodeMsg.NOT_FOUND);
        //     }
        //
        //     //判断是否是第一次开票
        //     if (StringUtils.isNotBlank(invoiceRecord.getImgUrl()) && StringUtils.isNotBlank(invoiceRecord.getPdfUrl())) {
        //
        //         //如果不是第一次查询开票，就直接返回对应的信息
        //         notice.setInvoiceRecord(invoiceRecord);
        //     } else {
        //
        //         //是第一次开票则查询开票信息
        //         HashMap<String, Object> map = new HashMap<>();
        //         map.put("identity", basicConfiguration.getIdentity());
        //         map.put("fpqqlsh", new String[]{invoiceRecord.getFpqqlsh()});
        //         String order = DESDZFP.encrypt(new JSONObject(map) + "");
        //
        //         HashMap<String, String> serialNumberMap = new HashMap<>();
        //         serialNumberMap.put("url", "/queryNnfpbox");
        //         serialNumberMap.put("order", order);
        //
        //         notice.setSerialNumberMap(serialNumberMap);
        //     }
        // }
    }

    /**
     * @Description: 微信端-好房快租-查询所有的房间
     * @author zhuliang
     * @date 2020/12/25 19:35
     */
    @Override
    public Result<List<CcmsSmartleasingRoom>> getAllRoom(QueryCriteria queryCriteria) {
        //查询所有房间信息
        List<CcmsSmartleasingRoom> rooms = roomMapper.getAllByRent((queryCriteria.getPage() - 1) * queryCriteria.getPageSize(), queryCriteria.getPageSize());

        //拿取图片第一张,得到所有的配套设施id
        for (CcmsSmartleasingRoom room : rooms) {
            if (null != room && StringUtils.isNotBlank(room.getRoomPicture())) {
                String[] split = room.getRoomPicture().split(",");
                room.getHouseType().setApartmentRenderingsList(split);
            }
            if (null != room && StringUtils.isNotBlank(room.getHouseType().getSupportingFacilities())) {
                String[] split2 = room.getHouseType().getSupportingFacilities().split(",");
                room.getHouseType().setSupportingFacilitiesList(split2);
            }
        }

        return Result.success(rooms);
    }

    /**
     * @Description: 微信端-好房快租-条件查询所有的房间
     * @author zhuliang
     * @date 2020/12/25 19:35
     */
    @Override
    public Result<List<CcmsSmartleasingRoom>> getWechatRoomByCondition(QueryCriteria queryCriteria) {
        //查询所有房间信息
        List<CcmsSmartleasingRoom> rooms = roomMapper.getAllByRentAndCondition((queryCriteria.getPage() - 1) * queryCriteria.getPageSize(),
                queryCriteria.getPageSize(),
                queryCriteria.getCityId(),
                queryCriteria.getAreaId(),
                queryCriteria.getProvinceId());

        //拿取图片第一张,得到所有的配套设施id
        for (CcmsSmartleasingRoom room : rooms) {
            if (null != room && StringUtils.isNotBlank(room.getRoomPicture())) {
                String[] split = room.getRoomPicture().split(",");
                room.getHouseType().setApartmentRenderingsList(split);
            }
            if (null != room && StringUtils.isNotBlank(room.getHouseType().getSupportingFacilities())) {
                String[] split2 = room.getHouseType().getSupportingFacilities().split(",");
                room.getHouseType().setSupportingFacilitiesList(split2);
            }
        }

        return Result.success(rooms);
    }

    /**
     * @Description: 微信端-好房快租-根据房间id查询房间信息
     * @author zhuliang
     * @date 2020/12/25 19:35
     */
    @Override
    public Result getWechatRoomById(String pkRoomId) {
        //根据id查询房间信息
        CcmsSmartleasingRoom room = roomMapper.getDetailsByWechat(pkRoomId);

        //拿取图片
        if (null != room && StringUtils.isNotBlank(room.getRoomPicture())) {
            String[] split = room.getRoomPicture().split(",");
            room.getHouseType().setApartmentRenderingsList(split);
        }

        //拿取配套设施
        if (null != room && StringUtils.isNotBlank(room.getHouseType().getSupportingFacilities())) {
            String[] split2 = room.getHouseType().getSupportingFacilities().split(",");
            room.getHouseType().setSupportingFacilitiesList(split2);
        }

        return Result.success(room);
    }

    /**
     * @Description: 微信端-修改密码
     * @author zhuliang
     * @date 2021/1/8 10:39
     */
    @Override
    public Result changePassword(CcmsSmartleasingTenant tenant) {
        //从redis中拿取验证码
        Object code = redisTemplate.opsForValue().get("updateVerificationCode:" + tenant.getContactPhone());

        //判断验证码是否正确
        if (null == code || "null".equals(code) || "".equals(code) || !code.equals(tenant.getCode())) {
            log.error(CodeMsg.VERIFICATION_CODE_ERROR.toString() + "-->电话：" + tenant.getContactPhone() + "-->用户验证码：" + tenant.getCode() + "-->验证码：" + code);
            return Result.error(CodeMsg.VERIFICATION_CODE_ERROR);
        }

        //修改密码
        tenantMapper.resetPassword(new Date(), 0, tenant.getTenantPassword(), null, tenant.getContactPhone());

        return Result.success();
    }

    /**
     * @Description: 微信端-添加发票图片和发票pdf文件
     * @author zhuliang
     * @date 2021/2/2 10:15
     */
    @Override
    public Result addInvoicePicture(String imgUrl, String pdfUrl, String pkInvoiceRecordId) {
        //定义要存放的开票信息实体类
        CcmsSmartleasingInvoiceRecord smartleasingInvoiceRecord = new CcmsSmartleasingInvoiceRecord();
        smartleasingInvoiceRecord.setPkInvoiceRecordId(pkInvoiceRecordId)
                .setImgUrl(imgUrl)
                .setPdfUrl(pdfUrl);

        //写入数据库
        invoiceRecordMapper.updateById(smartleasingInvoiceRecord);

        return Result.success();
    }

    /**
     * @Description: 微信端-生成预支付订单
     * @author zhuliang
     * @date 2020/12/25 10:36
     */
    @Override
    public Result wechatPreOrder(String token, String pkNoticeId, String sandBoxXml) {
        //得到租户联系方式
        String phone = JWT.decode(token).getClaim("phone").asString();

        //查询是否已经下单
        Object o = redisTemplate.opsForValue().get("PrepaidOrder:" + pkNoticeId);

        if (null != o) {
            //生成返回前端页面的json数据
            HashMap<String, String> payMap = (HashMap<String, String>) o;

            log.info("返回前端的支付数据: {}" , JSON.toJSONString(payMap));

            return Result.success(payMap);
        }

        //获得支付金额，和openid
        String openId = tenantMapper.getOpenID(phone);
        BigDecimal totalAmount = noticeMapper.getTotalAmount(pkNoticeId);
//         BigDecimal totalAmount = new BigDecimal(1.01);

        //兼容性处理
        if (StringUtils.isBlank(openId)) {
            log.error(CodeMsg.FAILED_TOOBTAIN_INFORMATION.toString() + "-->从数据库拿取对应的openid失败-->" + phone);
            return Result.error(CodeMsg.FAILED_TOOBTAIN_INFORMATION);
        }
        if (null == totalAmount) {
            log.error(CodeMsg.FAILED_TOOBTAIN_INFORMATION.toString() + "-->从token中获取的" + phone + "的支付金额失败");
            return Result.error(CodeMsg.FAILED_TOOBTAIN_INFORMATION);
        }

        //生成唯一订单号
        String orderNo;
        while (true) {
            orderNo = OrderNumberUtil.toPayCode(phone);

            //查询是否有此订单号
            String judgmentRepeat = noticeMapper.judgmentRepeat(orderNo);
            if (StringUtils.isBlank(judgmentRepeat)) {
                break;
            }
        }

        //发送请求进行统一下单，并生成返回前端的map数据
        Map<String, Object> parameterMap = new HashMap<>();

        try {
            //将金额转换为分
            int amount = totalAmount.multiply(new BigDecimal(100)).intValue();

            //生成ip
            String ip = WXPayUtil.getIp(request);
            //定义一个集合
            Map<String, String> packageParams = new HashMap<>();
            packageParams.put("appid", basicConfiguration.getAppId());
            packageParams.put("mch_id", basicConfiguration.getMchId());
            packageParams.put("nonce_str", WXPayUtil.generateNonceStr());
            packageParams.put("body", ConstantConfiguration.BODY);
            packageParams.put("out_trade_no", orderNo);
            packageParams.put("notify_url", basicConfiguration.getNotifyUrl());// 回调地址
            packageParams.put("openid", openId);
            packageParams.put("spbill_create_ip", ip);
            packageParams.put("sign_type", "MD5");
            packageParams.put("total_fee",amount + "");
            packageParams.put("trade_type", "JSAPI"); // 交易类型 JSAPI -JSAPI支付 NATIVE -Native支付 APP -APP支付

            // // 生成签名sign
            // if (StringUtils.isNotBlank(sandBoxXml)) {
            //     //将xml数据转换为map
            //     Map<String, String> sandBoxKey = WXPayUtil.xmlToMap(sandBoxXml);
            //
            //     //判断是否成功
            //     if (!"SUCCESS".equals(sandBoxKey.get("return_code"))) {
            //         return Result.error(new CodeMsg(20000, sandBoxKey.get("return_msg")));
            //     }
            //
            //     log.info("微信支付测试key--->" + sandBoxKey);
            //
            //     redisTemplate.opsForValue().set("sandboxKey:" + orderNo, sandBoxKey.get("sandbox_signkey"), 2, TimeUnit.HOURS);
            //
            //     packageParams.put("sign",  WXPayUtil.generateSignature(packageParams, sandBoxKey.get("sandbox_signkey")));
            //
            // } else {
            //     //获得沙箱key
            //     HashMap<String, String> sandBoxKeyMap = getSandBoxKey(basicConfiguration.getMchId(), basicConfiguration.getMchKey());
            //     parameterMap.put("sandBoxKeyMap", sandBoxKeyMap);
            // }
           packageParams.put("sign", WXPayUtil.generateSignature(packageParams, basicConfiguration.getMchKey()));

            //将map转换未xml格式
            String prepayXml = WXPayUtil.mapToXml(packageParams);

            //返回统一下单信息
            log.info("发送统一请求接口参数,{}",packageParams.toString());
            parameterMap.put("prepayXml", prepayXml);
            parameterMap.put("orderNo", orderNo);
            // parameterMap.put("wxPayUnifiedOrderUrl", "/apiMchWxQq/sandboxnew/pay/unifiedorder");
            parameterMap.put("wxPayUnifiedOrderUrl", "/apiMchWxQq/pay/unifiedorder");

            //将订单号写入到数据库
            noticeMapper.updateOrderNumber(new Date(), 0, pkNoticeId, orderNo);
        } catch (Exception e) {
            log.error(CodeMsg.WECHAT_PAY_ORDER_IS_ABNORMAL.toString() + "-->" + e);
            return Result.error(CodeMsg.WECHAT_PAY_ORDER_IS_ABNORMAL);
        }

        return Result.success(parameterMap);
    }

    /**
     * @Description: 获取微信支付沙箱测试的key
     * @author zhuliang
     * @date 2021/1/11 18:48
     */
    private HashMap<String, String> getSandBoxKey(String mchId, String mchKey) throws Exception {
        HashMap<String, String> sandBoxKeyMap = new HashMap<>();
        HashMap<String, String> data = new HashMap<>();
        // 商户号
        data.put("mch_id", mchId);

        //获取随机字符串
        data.put("nonce_str", WXPayUtil.generateNonceStr());

        //生成签名
        String sign = WXPayUtil.generateSignature(data, mchKey, com.github.wxpay.sdk.WXPayConstants.SignType.MD5);
        data.put("sign", sign);

        //将map转换为xml格式
        String xmlStr = WXPayUtil.mapToXml(data);

        //组装返回值
        sandBoxKeyMap.put("url", "/apiMchWxQq/sandboxnew/pay/getsignkey");
        sandBoxKeyMap.put("sandBoxKeyXml", xmlStr);

        return sandBoxKeyMap;
    }

    /**
     * @Description: 微信端-接收微信支付下单返回值
     * @author zhuliang
     * @date 2021/2/3 9:14
     */
    @Override
    public Result getWeChatJspiPayData(String xmlStr, String orderNo, String pkNoticeId) {
        try {
            //将xml转换为map集合
            Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);

            // 获取预支付交易会话标识
            String prepay_id = map.get("prepay_id");

            //生成返回前端页面的json数据
            Map<String, String> payMap = new HashMap<>();
            payMap.put("appId", basicConfiguration.getAppId());
            payMap.put("timeStamp", WXPayUtil.getCurrentTimestamp() + "");
            payMap.put("nonceStr",  WXPayUtil.generateNonceStr());
            payMap.put("signType", "MD5");
            payMap.put("package", "prepay_id=" + prepay_id);

            //封装前台数据签名
            String paySign = WXPayUtil.generateSignature(payMap, basicConfiguration.getMchKey());
            payMap.put("sign", paySign);
            payMap.put("no", orderNo);

            //将预支付订单号和随机字符串写入到redis中并设置过期时间
            redisTemplate.opsForValue().set("PrepaidOrder:" + pkNoticeId, payMap, 2, TimeUnit.HOURS);

            log.info("返回前端的支付数据: {}" , JSON.toJSONString(payMap));

            return Result.success(payMap);
        } catch (Exception e) {
            log.error(CodeMsg.WECHAT_PAY_ORDER_IS_ABNORMAL.toString() + "-->" + e);
            return Result.error(CodeMsg.WECHAT_PAY_ORDER_IS_ABNORMAL);
        }
    }

    /**
     * @Description: 微信端-支付结果回调地址
     * @author zhuliang
     * @date 2020/12/25 11:53
     */
    @Override
    public Result getPayNotify(HttpServletRequest request, HttpServletResponse response) {
        InputStream is = null;
        String resXML;
        try {
            //获取请求的流信息
            is = request.getInputStream();

            //解析请求流信息
            String xml = WXPayUtil.inputStream2String(is, "UTF-8");

            //将微信发的xml转map
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(xml);
            log.info("支付回调返回的数据：{}", JSON.toJSONString(notifyMap));

            // 验签返回的数据
           if (WXPayUtil.generateSignature(notifyMap, basicConfiguration.getMchKey()).equals(notifyMap.get("sign"))
                   && basicConfiguration.getMchId().equals(notifyMap.get("mch_id"))
                   && ("JSAPI".equals(notifyMap.get("trade_type")))) {
            // String no = (String) redisTemplate.opsForValue().get("sandboxKey:" + notifyMap.get("out_trade_no"));
            // if (WXPayUtil.generateSignature(notifyMap, no).equals(notifyMap.get("sign"))
            //         && basicConfiguration.getMchId().equals(notifyMap.get("mch_id"))
            //         && ("JSAPI".equals(notifyMap.get("trade_type")))) {
                if(notifyMap.get("return_code").equals(ConstantConfiguration.SUCCESS)){
                    resXML = ConstantConfiguration.NOTIFY_RESPONSE_BODY;
                    log.info("支付回调结果校验成功");

                    String orderNo = notifyMap.get("out_trade_no"); //商户订单号
                    String amount = notifyMap.get("total_fee"); //实际支付的订单金额:单位分
                    String transactionId = notifyMap.get("transaction_id"); //微信支付订单号
                    String timeEnd = notifyMap.get("time_end"); //支付完成时间，格式为yyyyMMddHHmmss

                    //支付成功，处理逻辑
                    successPay(orderNo, amount, transactionId, timeEnd);
                    log.info("微信支付回调：修改订单支付状态成功--》" + orderNo);

                }else {
                    resXML = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[" + notifyMap.get("err_code_des") + "]]></return_msg>" + "</xml> ";
                    log.info("支付失败:{}",JSON.toJSONString(notifyMap));
                }
                response.getWriter().write(resXML);

                return Result.success();
            }else{
                log.info("支付回调结果校验失败-->" + notifyMap.toString());
                return Result.success();
            }
        } catch (Exception e) {
            log.error("支付回调异常-->" + e);
            return Result.success();
        }finally {
            if(null != is){
                try {
                    is.close();
                    log.error("关闭流成功--->");
                } catch (IOException e) {
                    log.error("关闭流失败--->" + e);
                }
            }
        }
    }

    /**
     * @Description: 支付成功，处理逻辑方法
     * @author zhuliang
     * @date 2020/12/31 10:07
     */
    @Transactional
    public void successPay(String orderNo, String amount, String transactionId, String timeEnd) throws Exception {
        //查询数据库是否已经修改了状态
        String payStatus = noticeMapper.getPayStatus(null, orderNo);

        if (StringUtils.isNotBlank(payStatus)) {
            return;
        }

        //设置日期格式
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = dateFormat.parse(timeEnd);

        //将金额转换位元
        BigDecimal amountActuallyPaid = BigDecimal.valueOf(Long.valueOf(amount)).divide(new BigDecimal(100));

        //修改数据库信息
        noticeMapper.updateByPaySuccess(new Date(), 0, orderNo, date, amountActuallyPaid, transactionId);

        //查询缴费的费用单月份
        Date paymentDate = noticeMapper.checkMonthPayment(orderNo);

        //判断是否是本月的缴费
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(paymentDate);
        c2.setTime(new Date());
        int  year = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
        int month = c2.get(Calendar.MONTH)+year*12 - c1.get(Calendar.MONTH);



        if (1 <= month) {
            //累加历史金额
            historicalPaymentMapper.updateByWechat(amountActuallyPaid, new Date(), 0, orderNo);
            regionalAnalysisMapper.updateByWechat(amountActuallyPaid, new Date(), 0, orderNo);
        }
    }

    /**
     * @Description: 微信端-查询支付结果
     * @author zhuliang
     * @date 2020/12/25 18:02
     */
    @Override
    public Result checkPaymentResult(String token, String pkNoticeId, String checkingOrderXml) {
        //查询数据库支付状态
        String payStatus = noticeMapper.getPayStatus(pkNoticeId, null);
        // String payStatus = "";

        //如果支付成功，则返回
        if (StringUtils.isNotBlank(payStatus)) {
            log.info("支付查单-->支付成功");
            return Result.success();
        } else {
            //获得订单号
            String orderNumber = null;
            Object o = redisTemplate.opsForValue().get("PrepaidOrder:" + pkNoticeId);
            if (null == o) {
                orderNumber = noticeMapper.selectById(pkNoticeId).getOrderNumber();
            } else {
                HashMap<String, String> map = (HashMap<String, String>) o;
                orderNumber = map.get("no");
            }

            Map<String, String> map = new HashMap<>();
            if (StringUtils.isBlank(checkingOrderXml)) {
                try {
                    //调用查单接口
                    //组装查询数据
                    Map<String, String> paraMap = new HashMap<>();
                    paraMap.put("appid",basicConfiguration.getAppId());
                    paraMap.put("mch_id",basicConfiguration.getMchId());
                    paraMap.put("nonce_str",WXPayUtil.generateNonceStr());   //随机字符串，长度要求在32位以内。
                    paraMap.put("out_trade_no",orderNumber);
                    // String s = (String) redisTemplate.opsForValue().get("sandboxKey:" + orderNumber);
                    // paraMap.put("sign",  WXPayUtil.generateSignature(paraMap, s));
                   String sign = WXPayUtil.generateSignature(paraMap, basicConfiguration.getMchKey());//签名
                   paraMap.put("sign", sign);

                    //将查询数据转换为xml格式
                    String xml = WXPayUtil.mapToXml(paraMap);//将map转成xml格式的 字符串(微信只接受xml格式的字符串)

                    map.put("checkXml", xml);
                    // map.put("url", "/apiMchWxQq/sandboxnew/pay/orderquery");
                    map.put("url", "/apiMchWxQq/pay/orderquery");

                    log.info("返回前端查单数据-->" + map.toString());
                    return Result.success(map);
                } catch (Exception e) {
                    log.error(CodeMsg.ASSEMBLY_CHECK_DATA_ABNORMAL.toString() + "-->" + e);
                    return Result.error(CodeMsg.ASSEMBLY_CHECK_DATA_ABNORMAL);
                }
            } else {

                //将xml数据转换为map数据
                try {
                    map = WXPayUtil.xmlToMap(checkingOrderXml);
                } catch (Exception e) {
                    log.error(CodeMsg.IllegalArgumentException.toString() + "-->微信查询结果转换为map集合异常-->" + e);
                    return Result.error(CodeMsg.IllegalArgumentException);
                }

                //判断查单结果
                if ("SUCCESS".equals(map.get("trade_state"))){
                    log.info("支付回调结果--》校验成功");
                    String orderNo = map.get("out_trade_no"); //商户订单号

                    //校验订单号是否一致
                    if (!orderNo.equals(orderNumber)) {
                        log.error(CodeMsg.PAYMENT_EXCEPTION.toString() + "-->支付查询，订单号不匹配异常-->查询订单号:" + orderNumber + "-->得到订单号：" + orderNo);
                        return Result.error(CodeMsg.PAYMENT_EXCEPTION);
                    }

                    String amount = map.get("total_fee"); //实际支付的订单金额:单位分
                    String transactionId = map.get("transaction_id"); //微信支付订单号
                    String timeEnd = map.get("time_end"); //支付完成时间，格式为yyyyMMddHHmmss
                    //支付成功，处理逻辑
                    try {
                        successPay(orderNo, amount, transactionId, timeEnd);
                        log.info("微信支付回调：修改订单支付状态成功--》" + orderNo);
                        return Result.success();
                    } catch (Exception e) {
                        log.error(CodeMsg.PAYMENT_EXCEPTION.toString() + "-->微信支付回调：修改订单支付状态失败--》" + orderNo);
                        return Result.error(CodeMsg.PAYMENT_EXCEPTION);
                    }
                } else {
                    log.error(CodeMsg.PAYMENT_EXCEPTION.toString() + "-->微信查单结果不成功：" + map.get("trade_state") + "-->订单号:" + orderNumber);
                    return Result.error(new CodeMsg(20000, map.get("trade_state") + "--请联系工作人员"));
                }
            }
        }
    }
}
